Conversation
kelsey-steven-ada
left a comment
There was a problem hiding this comment.
Great work! Let me know if you have questions on any of the feedback ^_^
| <h1>Chatroom: {chatData[0].sender} and {chatData[1].sender}</h1> | ||
| <section id='heartWidget'> | ||
| <span className='widget'>{likedCount} ❤️s</span> | ||
| <DarkMode currentTheme={theme} toggleTheme={toggleDarkMode}/> |
There was a problem hiding this comment.
Love the theme toggle!
| setTheme(mode); | ||
| }; | ||
|
|
||
| const likedCount = chatData.filter((chat) => chat.liked).length; |
There was a problem hiding this comment.
Great work calculating the hearts count from the chatsData! Since we don't need the contents of the array we get from filter, another option is to use a higher order function like array.reduce to take our list of messages and reduce it down to a single value.
// This could be returned from a helper function
// totalLikes is a variable that accumulates a value as we loop over each entry in chatEntries
const likedCount = chatEntries.reduce((totalLikes, currentMessage) => {
// If currentMessage.liked is true add 1 to totalLikes, else add 0
return (totalLikes += currentMessage.liked ? 1 : 0);
}, 0); // The 0 here sets the initial value of totalLikes to 0| if (chat.id === id) { | ||
| return { ...chat, liked: !chat.liked }; | ||
| } else { | ||
| return chat; |
There was a problem hiding this comment.
Nice managing of data & making sure we return a new object when we need to alter a message in our list.
| const toggleDarkMode = (mode) => { | ||
| setTheme(mode); | ||
| }; |
There was a problem hiding this comment.
Since we aren't taking any other actions with the mode argument, I think we could factor out the toggleDarkMode function and pass setTheme directly to the DarkMode component.
| const [chatData, setChatData] = useState(CHATS); | ||
| const [theme, setTheme] = useState('App'); | ||
|
|
||
| const handleLikedMessages = (id) => { | ||
| setChatData(chatData => chatData.map(chat => { | ||
| if (chat.id === id) { | ||
| return { ...chat, liked: !chat.liked }; | ||
| } else { | ||
| return chat; | ||
| } | ||
| })); | ||
| }; | ||
|
|
||
| const toggleDarkMode = (mode) => { | ||
| setTheme(mode); | ||
| }; | ||
|
|
||
| const likedCount = chatData.filter((chat) => chat.liked).length; |
There was a problem hiding this comment.
It can be a little easier to read and understand code when we co-locate variables rather than placing them in-between functions. One possible re-organization could look like:
const [chatData, setChatData] = useState(CHATS);
const [theme, setTheme] = useState('App');
const likedCount = chatData.filter((chat) => chat.liked).length;
const handleLikedMessages = (id) => {
setChatData(chatData => chatData.map(chat => {
if (chat.id === id) {
return { ...chat, liked: !chat.liked };
} else {
return chat;
}
}));
};
const toggleDarkMode = (mode) => {
setTheme(mode);
};|
|
||
| const filledHeart = liked ? '❤️' : '🤍'; | ||
|
|
||
| const setMessageBubble = id%2 ? 'local' : 'remote'; |
There was a problem hiding this comment.
| const setMessageBubble = id%2 ? 'local' : 'remote'; | |
| const setMessageBubble = id % 2 ? 'local' : 'remote'; |
| </section> | ||
| </div> | ||
| <> | ||
| <div className={`chat-entry ${setMessageBubble}`}> |
There was a problem hiding this comment.
Great use of a variable and interpolated string to form the className value.
| id: PropTypes.number.isRequired, | ||
| sender: PropTypes.string.isRequired, | ||
| body: PropTypes.string.isRequired, | ||
| timeStamp: PropTypes.string.isRequired, | ||
| liked: PropTypes.bool.isRequired, | ||
| onLiked: PropTypes.func.isRequired, |
There was a problem hiding this comment.
Nice use of Prop-Types and flagging those necessary for render with isRequired!.
| import ChatEntry from './ChatEntry'; | ||
|
|
||
| const ChatLog = ({ entries, onLiked }) => { | ||
| const chatEntryComponents = entries.map((entry) => { |
There was a problem hiding this comment.
Nice mapping! 🙌🏻
| }; | ||
|
|
||
| ChatLog.propTypes = { | ||
| entries: PropTypes.arrayOf(PropTypes.shape({ |
There was a problem hiding this comment.
Nice use of PropTypes.arrayOf and PropTypes.shape!
No description provided.